package com.tcm.invite.service;

import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.base.core.codec.Base64Utils;
import com.base.core.codec.TripleDesUtils;
import com.base.core.exception.ServiceException;
import com.base.core.lang.DateUtils;
import com.base.core.lang.LocalDateTimeUtils;
import com.base.core.lang.StringUtils;
import com.base.core.utils.R;
import com.base.genid.generator.UidGenerator;
import com.tcm.invite.domain.dto.InviteRecordDTO;
import com.tcm.invite.domain.vo.InviterVO;
import com.tcm.invite.util.WXCryptUtil;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

@DubboService(version = "0.0.1-alpha", retries = 3, timeout = 3000)
public class InviteServiceImpl implements InviteService {

    @Autowired
    private InviteRecordService inviteRecordService;

    @DubboReference(version = "0.0.1-beta", group = "cached-uid", retries = 3, check = false, timeout = 3000)
    private UidGenerator uidGenerator;

    @Override
    public InviterVO findByInviteCode(String inviteCode, String spreadType) {
       InviteRecordDTO inviteRecordDTO = inviteRecordService.findByInvitedCode(inviteCode, spreadType);
       InviterVO inviterVO = null;
       if(inviteRecordDTO != null){
           BeanUtils.copyProperties(inviteRecordDTO, inviterVO);
       }
       return inviterVO;
    }

    /**
     * 创建邀请链接
     * @param cellphone
     * @return
     */
    @Override
    public String createInviteLink(String cellphone, String spreadType) throws ServiceException {
        try {
            String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
            String str = "";
            for (int i = 0; i < 10; i++) {
                str = str + chars.charAt((int) (Math.random() * 52));
            }
            String param = str + TripleDesUtils.encrypt(cellphone + DateUtils.getDateTime(), "doyoubeeninvited");
            String url = "http://spread.zetikeji.com/index?spread=" + spreadType
                    + "&param=" + URLEncoder.encode(param, "utf8");
            return url;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * 创建邀请关系邀请链接
     * @param cellphone
     * @return
     */
    @Override
    public String createInviteFriendLink(String cellphone, String invitePhone) throws ServiceException {
        try {
            String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
            String str = "";
            for (int i = 0; i < 10; i++) {
                str = str + chars.charAt((int) (Math.random() * 52));
            }
            String param = str + TripleDesUtils.encrypt(cellphone + DateUtils.getDateTime(), "doyoubeeninvited");
            String inviteParam = str + TripleDesUtils.encrypt(invitePhone + DateUtils.getDateTime(), "doyoubeeninvited");
            param += "|" + inviteParam;
            String url = "http://spread.zetikeji.com/invite?action=friend"
                    + "&target=user&param=" + URLEncoder.encode(param, "utf8");
            return url;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
      * 邀请二维码
      *
      * @param cellphone
      * @return
      */
    @Override
    public String inviteQrcode(String cellphone, String spreadType) {
        QrConfig qrConfig = new QrConfig();
        qrConfig.setCharset(Charset.defaultCharset());
        qrConfig.setHeight(210);
        qrConfig.setWidth(210);
        qrConfig.setMargin(1);
        String json = createInviteLink(cellphone, spreadType);
        byte[] bytes = QrCodeUtil.generatePng(json, qrConfig);
        return Base64Utils.simpleEncode(bytes);
    }

    /**
     * 保存邀请数据信息
     * @param param 邀请人传递的参数 加密的cellphone用竖线隔开拼接邀请人手机号
     */
    @Override
    public R saveInviteInfo(String spreadType, String param) throws ServiceException {
        try {
            if(StringUtils.isBlank(spreadType) || StringUtils.isBlank(param)){
                return R.fail("参数异常");
            }
            String decodeParam = URLDecoder.decode(param,"utf8");
            String[] paramList = decodeParam.split("\\|");
            String urlcode = URLDecoder.decode(paramList[0], "utf8");
            String secretPhone = TripleDesUtils.decrypt(urlcode.substring(10, urlcode.length())
                    .replaceAll(" ", "+"), "doyoubeeninvited");
            if (null != secretPhone && paramList[1].length() == 11) {
                String phone = paramList[1];
                String cellPhone = secretPhone.substring(0, 11);
                if(cellPhone.equals(phone)){
                    return R.fail("不能邀请自己");
                }
                InviteRecordDTO entity = new InviteRecordDTO();
                entity.setCellphone(cellPhone);
                entity.setInvitedCode(phone);
                entity.setStatus(new Byte("1"));
                entity.setSpreadType(spreadType);
                entity.setId(uidGenerator.getUID());
                entity.setCreateTime(LocalDateTime.now());
                //查询关系，一个号码只能被邀请一次
                InviteRecordDTO inviteRecordDTO = inviteRecordService.findByInvitedCode(phone,spreadType);
                if(inviteRecordDTO == null){
                    inviteRecordService.insert(entity);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return R.fail(ex.getMessage());
        }
        return R.success();
    }

    /**
     * 微信授权手机号
     * @param encryptedData
     * @param iv
     * @param session_key
     * @return
     */
    @Override
    public Map<String,String> getPhoneNumber(String encryptedData, String iv, String session_key) {
        Map<String,String> map=new HashMap<>();

        String result= WXCryptUtil.decrypt(encryptedData,session_key,iv);
        JSONObject json = JSONObject.parseObject(result);

        if (!StringUtils.isEmpty(result) && result.length() > 0) {
            map.put("purePhoneNumber", json.getString("purePhoneNumber"));
            map.put("phoneNumber", json.getString("phoneNumber"));
            map.put("countryCode", json.getString("countryCode"));
            map.put("msg","success");
            return map;
        }
        map.put("msg", "error");
        return map;
    }

    /**
     * 小程序授权登录
     */
    @Override
    public  Map<String,String> miniLogin(String code){
        Map<String,String> map=new HashMap<>();

        Map<String, Object> params = new HashMap<>();
        params.put("appid", "wx5c03c7e37a7921d3");
        params.put("secret","708be554a3d7177f329a0547ea4d42d5");
        params.put("js_code",code);
        params.put("grant_type", "authorization_code");
        String s= HttpUtil.get("https://api.weixin.qq.com/sns/jscode2session", params);
        if (StringUtils.isEmpty(s)){
            map.put("msg","error");
            return map;
        }
        JSONObject jsonObject = JSONObject.parseObject(s);
        String session_key=jsonObject.getString("session_key");
        String openid=jsonObject.getString("openid");
        String unionid=jsonObject.getString("unionid");
        map.put("unionid",unionid);
        map.put("session_key",session_key);
        map.put("openid",openid);
        map.put("msg","success");
        return map;

    }

}
